package com.shirojwt.shiro;

import com.shirojwt.entity.Account;
import com.shirojwt.service.AccountService;
import com.shirojwt.utils.JwtUtil;
import io.jsonwebtoken.Jwt;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * @author chenguo
 * @date 2021/10/12 10:55 上午
 */
@Slf4j
public class AccountRealm extends AuthorizingRealm {

    @Resource
    private AccountService accountService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("==========user is authorizing==========");
        String username = JwtUtil.getUsernameFromToken(principalCollection.toString());
        Account account = accountService.findByUsername(username);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.addStringPermission(account.getPerms());
        info.addRole(account.getRole());
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("身份认证");
        String token = (String) authenticationToken.getCredentials();

        String username = JwtUtil.getUsernameFromToken(token);
        Account account = accountService.findByUsername(username);
        if(!StringUtils.hasLength(username)||!JwtUtil.verify(token, username)){
            log.error("token认证失败！！");
            throw new AuthenticationException("token 认证失败");
        }
        if(null == account){
            log.error("账号会密码错误！！");
            throw new AuthenticationException("账号或密码错误");
        }
        log.info("用户{}认证成功！", account.getUsername());

        return new SimpleAuthenticationInfo(token, token, getName());

    }
}
